#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <QDebug>

#include "settings.h"
#include "mainwindow.h"

#define UPDATE_TO_DEVICE(x) if (serialPort->isOpen()) newDataToDevice((quint8 *)&x, (quint16)((quint64)&x - (qint64)&settings), sizeof(x))

Settings::Settings() {
  for (quint8 i=0;i<SETTING_AUDIO_ROUTE_OFFSET_COUNT;i++) {
    settings.audio.af_input_source_cw[i] = 0;
    settings.audio.af_input_source_digital[i] = 0;
    settings.audio.af_input_source_phone[i] = 0;
    settings.audio.mic_path[i] = 0;
    settings.audio.mic_mute[i] = 0;
    settings.audio.mic_preamp[i] = 0;
    settings.audio.line_out_mute_phone[i] = 0;
    settings.audio.line_out_mute_digital[i] = 0;
    settings.audio.computer_generated_path_phone[i] = 0;
    settings.audio.computer_generated_path_digital[i] = 1;
  }
}

void Settings::setSerialPtr(CommClass *ptr) {
  serialPort = ptr;
}

void Settings::newDataToDevice(quint8 *data, quint16 offset, quint8 length) {
  serialPort->addTXMessageSendStruct(SRI_CMD_SEND_SETTINGS, length, offset, (quint8 *)data);
}

void Settings::newDataToStruct(quint8 *data, quint16 offset, quint8 length) {
  unsigned char *ptr;
  ptr = (unsigned char *)&settings;

  for (unsigned char i=0;i<length;i++) {
    *(ptr+offset+i) = data[i];
  }
}

void Settings::saveToEEPROM() {
  serialPort->addTXMessage(SRI_CMD_EEPROM_SAVE);
}

/*********** START RADIO SETTINGS ***********/
void Settings::setRadioModel(quint8 value) {
  settings.radio.radio_model = value;

  UPDATE_TO_DEVICE(settings.radio.radio_model);
}

void Settings::setRadioCATInterfaceEnabled(bool state) {
  if (state)
    settings.radio.cat_interface_enabled = 1;
  else
    settings.radio.cat_interface_enabled = 0;

  UPDATE_TO_DEVICE(settings.radio.cat_interface_enabled);
}

void Settings::setRadioCATBaudrate(quint32 value) {
  settings.radio.cat_baudrate = value;

  UPDATE_TO_DEVICE(settings.radio.cat_baudrate);
}

void Settings::setRadioCATStopbits(quint8 value) {
  settings.radio.cat_stopbits = value;

  UPDATE_TO_DEVICE(settings.radio.cat_stopbits);
}

void Settings::setRadioCATParity(quint8 value) {
  settings.radio.cat_parity = value;

  UPDATE_TO_DEVICE(settings.radio.cat_parity);
}

void Settings::setRadioCATICOMCIV(quint8 value) {
  settings.radio.cat_icom_civ = value;

  UPDATE_TO_DEVICE(settings.radio.cat_icom_civ);
}

void Settings::setRadioCATFlowControl(bool state) {
  if (state)
    settings.radio.cat_flow_control = 1;
  else
    settings.radio.cat_flow_control = 0;

  UPDATE_TO_DEVICE(settings.radio.cat_flow_control);
}

void Settings::setRadioCATJumperRTSCTS(bool state) {
  if (state)
    settings.radio.cat_jumper_rts_cts = 1;
  else
    settings.radio.cat_jumper_rts_cts = 0;

  UPDATE_TO_DEVICE(settings.radio.cat_jumper_rts_cts);
}

void Settings::setRadioCATRetrieveType(qint8 value) {
  settings.radio.cat_retrieve_type = value;

  UPDATE_TO_DEVICE(settings.radio.cat_retrieve_type);
}

void Settings::setRadioCATPollRate(qint16 value) {
  settings.radio.cat_poll_rate = value/10;

  UPDATE_TO_DEVICE(settings.radio.cat_poll_rate);
}

quint8 Settings::getRadioModel() {
  return(settings.radio.radio_model);
}

bool Settings::getRadioCATInterfaceEnabled() {
  if (settings.radio.cat_interface_enabled)
    return(true);

  return(false);
}

quint32 Settings::getRadioCATBaudrate() {
  return(settings.radio.cat_baudrate);
}

quint8 Settings::getRadioCATStopbits() {
  return(settings.radio.cat_stopbits);
}

quint8 Settings::getRadioCATParity() {
  return(settings.radio.cat_parity);
}

quint8 Settings::getRadioCATICOMCIV() {
  return(settings.radio.cat_icom_civ);
}

bool Settings::getRadioCATFlowControl() {
  if (settings.radio.cat_flow_control)
    return(true);

  return(false);
}

bool Settings::getRadioCATJumperRTSCTS() {
  if (settings.radio.cat_jumper_rts_cts)
    return(true);

  return(false);
}

quint8 Settings::getRadioCATRetrieveType() {
  return(settings.radio.cat_retrieve_type);
}

quint16 Settings::getRadioCATPollRate() {
  return(settings.radio.cat_poll_rate*10);
}

/*********** END RADIO SETTINGS ***********/

/*********** START PTT SETTINGS ***********/
void Settings::setPTTInputEnabled(quint8 input) {
  settings.ptt.ptt_input_enabled = input;

  UPDATE_TO_DEVICE(settings.ptt.ptt_input_enabled);
}

void Settings::setPTTInputInvert(quint8 input) {
  settings.ptt.ptt_input_invert = input;

  UPDATE_TO_DEVICE(settings.ptt.ptt_input_invert);
}

void Settings::setPTTRadioPreDelay(quint16 delay) {
  settings.ptt.radio_pre_delay = delay/10;

  UPDATE_TO_DEVICE(settings.ptt.radio_pre_delay);
}

void Settings::setPTTRadioPostDelay(quint16 delay) {
  settings.ptt.radio_post_delay = delay/10;

  UPDATE_TO_DEVICE(settings.ptt.radio_post_delay);
}

void Settings::setPTTAmpPreDelay(quint16 delay) {
  settings.ptt.amp_pre_delay = delay/10;

  UPDATE_TO_DEVICE(settings.ptt.amp_pre_delay);
}

void Settings::setPTTAmpPostDelay(quint16 delay) {
  settings.ptt.amp_post_delay = delay/10;

  UPDATE_TO_DEVICE(settings.ptt.amp_post_delay);
}

void Settings::setPTTInhibitPreDelay(quint16 delay) {
  settings.ptt.inhibit_pre_delay = delay/10;

  UPDATE_TO_DEVICE(settings.ptt.inhibit_pre_delay);
}

void Settings::setPTTInhibitPostDelay(quint16 delay) {
  settings.ptt.inhibit_post_delay = delay/10;

  UPDATE_TO_DEVICE(settings.ptt.inhibit_post_delay);
}

void Settings::setPTTAntennaPreDelay(quint16 delay) {
  settings.ptt.antenna_pre_delay = delay/10;

  UPDATE_TO_DEVICE(settings.ptt.antenna_pre_delay);
}

void Settings::setPTTAntennaPostDelay(quint16 delay) {
  settings.ptt.antenna_post_delay = delay/10;

  UPDATE_TO_DEVICE(settings.ptt.antenna_post_delay);
}

void Settings::setPTTOutputCWConf(quint8 value) {
  settings.ptt.radio_cw_ptt = value;

  UPDATE_TO_DEVICE(settings.ptt.radio_cw_ptt);
}

void Settings::setPTTOutputPhoneConf(quint8 value) {
  settings.ptt.radio_phone_ptt = value;

  UPDATE_TO_DEVICE(settings.ptt.radio_phone_ptt);
}

void Settings::setPTTOutputDigitalConf(quint8 value) {
  settings.ptt.radio_digital_ptt = value;

  UPDATE_TO_DEVICE(settings.ptt.radio_digital_ptt);
}

void Settings::setPTTOutputAmplifierEnabled(bool value) {
  if (value)
    settings.ptt.amplifier_enabled = 1;
  else
    settings.ptt.amplifier_enabled = 0;

  UPDATE_TO_DEVICE(settings.ptt.amplifier_enabled);
}

void Settings::setPTTOutputInhibitEnabled(bool value) {
  if (value)
    settings.ptt.inhibit_enabled = 1;
  else
    settings.ptt.inhibit_enabled = 0;

  UPDATE_TO_DEVICE(settings.ptt.inhibit_enabled);
}

quint8 Settings::getPTTInputEnabled() {
  return(settings.ptt.ptt_input_enabled);
}

quint8 Settings::getPTTInputInvert() {
  return(settings.ptt.ptt_input_invert);
}

bool Settings::getPTTInputEnabled(quint8 bitNr) {
  if (settings.ptt.ptt_input_enabled & (1<<bitNr))
    return(true);

  return(false);
}

bool Settings::getPTTInputInvert(quint8 bitNr) {
  if (settings.ptt.ptt_input_invert & (1<<bitNr))
    return(true);

  return(false);
}

quint16 Settings::getPTTRadioPreDelay() {
  return(settings.ptt.radio_pre_delay*10);
}

quint16 Settings::getPTTRadioPostDelay() {
  return(settings.ptt.radio_post_delay*10);
}

quint16 Settings::getPTTAmpPreDelay() {
  return(settings.ptt.amp_pre_delay*10);
}

quint16 Settings::getPTTAmpPostDelay() {
  return(settings.ptt.amp_post_delay*10);
}

quint16 Settings::getPTTInhibitPreDelay() {
  return(settings.ptt.inhibit_pre_delay*10);
}

quint16 Settings::getPTTInhibitPostDelay() {
  return(settings.ptt.inhibit_post_delay*10);
}

quint16 Settings::getPTTAntennaPreDelay() {
  return(settings.ptt.antenna_pre_delay*10);
}

quint16 Settings::getPTTAntennaPostDelay() {
  return(settings.ptt.antenna_post_delay*10);
}

quint8 Settings::getPTTOutputCWConf() {
  return(settings.ptt.radio_cw_ptt);
}

quint8 Settings::getPTTOutputPhoneConf() {
  return(settings.ptt.radio_phone_ptt);
}

quint8 Settings::getPTTOutputDigitalConf() {
  return(settings.ptt.radio_digital_ptt);
}

bool Settings::getPTTOutputAmplifierEnabled() {
  if (settings.ptt.amplifier_enabled)
    return(true);

  return(false);
}

bool Settings::getPTTOutputInhibitEnabled() {
  if (settings.ptt.inhibit_enabled)
    return(true);

  return(false);
}

/*********** END PTT SETTINGS ***********/

/*********** START AUDIO SETTINGS ***********/

void Settings::setAudioRoutingLineInSourceCW(quint8 index, quint8 state) {
  settings.audio.af_input_source_cw[index] = state;

  UPDATE_TO_DEVICE(settings.audio.af_input_source_cw);
}

void Settings::setAudioRoutingLineInSourcePhone(quint8 index, quint8 state) {
  settings.audio.af_input_source_phone[index] = state;

  UPDATE_TO_DEVICE(settings.audio.af_input_source_phone);
}

void Settings::setAudioRoutingLineInSourceDigital(quint8 index, quint8 state) {
  settings.audio.af_input_source_digital[index] = state;

  UPDATE_TO_DEVICE(settings.audio.af_input_source_digital);
}

void Settings::setAudioRoutingMicPath(quint8 index, quint8 state) {
  settings.audio.mic_path[index] = state;

  UPDATE_TO_DEVICE(settings.audio.mic_path);
}

void Settings::setAudioRoutingComputerGeneratedPathPhone(quint8 index, quint8 state) {
  settings.audio.computer_generated_path_phone[index] = state;

  UPDATE_TO_DEVICE(settings.audio.computer_generated_path_phone);}

void Settings::setAudioRoutingComputerGeneratedPathDigital(quint8 index, quint8 state) {
  settings.audio.computer_generated_path_digital[index] = state;

  UPDATE_TO_DEVICE(settings.audio.computer_generated_path_digital);
}

void Settings::setAudioRoutingMicMute(quint8 index, bool state) {
  settings.audio.mic_mute[index] = state;

  UPDATE_TO_DEVICE(settings.audio.mic_mute);
}

void Settings::setAudioRoutingMicPreamp(quint8 index, bool state) {
  settings.audio.mic_preamp[index] = state;

  UPDATE_TO_DEVICE(settings.audio.mic_preamp);
}

void Settings::setAudioRoutingMuteLineOutPhone(quint8 index, bool state) {
  settings.audio.line_out_mute_phone[index] = state;

  UPDATE_TO_DEVICE(settings.audio.line_out_mute_phone);
}

void Settings::setAudioRoutingMuteLineOutDigital(quint8 index, bool state) {
  settings.audio.line_out_mute_digital[index] = state;

  UPDATE_TO_DEVICE(settings.audio.line_out_mute_digital);
}

quint8 Settings::getAudioRoutingLineInSourceCW(quint8 index) {
  return(settings.audio.af_input_source_cw[index]);
}

quint8 Settings::getAudioRoutingLineInSourcePhone(quint8 index) {
  return(settings.audio.af_input_source_phone[index]);
}

quint8 Settings::getAudioRoutingLineInSourceDigital(quint8 index) {
  return(settings.audio.af_input_source_digital[index]);
}

quint8 Settings::getAudioRoutingMicPath(quint8 index) {
  return(settings.audio.mic_path[index]);
}

quint8 Settings::getAudioRoutingComputerGeneratedPathPhone(quint8 index) {
  return(settings.audio.computer_generated_path_phone[index]);
}

quint8 Settings::getAudioRoutingComputerGeneratedPathDigital(quint8 index) {
  return(settings.audio.computer_generated_path_digital[index]);
}

bool Settings::getAudioRoutingMicMute(quint8 index) {
  return(settings.audio.mic_mute[index]);
}

bool Settings::getAudioRoutingMicPreamp(quint8 index) {
  return(settings.audio.mic_preamp[index]);
}

bool Settings::getAudioRoutingMuteLineOutPhone(quint8 index) {
  return(settings.audio.line_out_mute_phone[index]);
}

bool Settings::getAudioRoutingMuteLineOutDigital(quint8 index) {
  return(settings.audio.line_out_mute_digital[index]);
}

/*********** END AUDIO SETTINGS ***********/
